package com.xnyzc.lhy.mis.service.impl.activity;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xnyzc.lhy.common.exception.ActivityException;
import com.xnyzc.lhy.common.penum.activity.ActivityErrorCode;
import com.xnyzc.lhy.common.util.DateUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.common.util.TokenUtil;
import com.xnyzc.lhy.mis.entity.activity.OaSysActivityDef;
import com.xnyzc.lhy.mis.entity.activity.OaSysActivityReward;
import com.xnyzc.lhy.mis.entity.param.activity.ActivityCityCreateParam;
import com.xnyzc.lhy.mis.entity.param.activity.ActivityCreateParam;
import com.xnyzc.lhy.mis.entity.param.activity.ActivityDefSearchParam;
import com.xnyzc.lhy.mis.entity.result.activity.ActivityDefSearchResult;
import com.xnyzc.lhy.mis.entity.result.activity.ActivityInfoPeriodResult;
import com.xnyzc.lhy.mis.entity.result.activity.ActivityInfoResult;
import com.xnyzc.lhy.mis.entity.result.activity.ActivityInfoRewardRuleResult;
import com.xnyzc.lhy.mis.entity.system.OaSysUser;
import com.xnyzc.lhy.mis.mapper.activity.OaSysActivityDefMapper;
import com.xnyzc.lhy.mis.mapper.system.OaSysUserMapper;
import com.xnyzc.lhy.mis.service.activity.IOaSysActivityDefService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnyzc.lhy.mis.service.activity.IOaSysActivityPeriodService;
import com.xnyzc.lhy.mis.service.activity.IOaSysActivityRewardRuleService;
import com.xnyzc.lhy.mis.service.activity.IOaSysActivityRewardService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.*;

/**
 * <p>
 * 活动定义 服务实现类
 * </p>
 *
 * @author haoyfa
 * @since 2019-12-16
 */
@Service
@Slf4j
public class OaSysActivityDefServiceImpl extends ServiceImpl<OaSysActivityDefMapper, OaSysActivityDef> implements IOaSysActivityDefService {

    @Autowired
    OaSysActivityDefMapper oaSysActivityDefMapper;

    @Autowired
    IOaSysActivityRewardRuleService iOaSysActivityRewardRuleService;

    @Autowired
    IOaSysActivityPeriodService iOaSysActivityPeriodService;

    @Autowired
    IOaSysActivityRewardService iOaSysActivityRewardService;

    @Autowired
    private OaSysUserMapper oaSysUserMapper;

    /**
     * 获取活动定义（含查询条件）
     * @param activityDefSearchParam
     * @return
     */
    @Override
    public List<ActivityDefSearchResult> queryActivityDefList(ActivityDefSearchParam activityDefSearchParam) {
        if(activityDefSearchParam == null)
        {
            throw new ActivityException(ActivityErrorCode.paramError);
        }

        //查询活动定义
        QueryWrapper<OaSysActivityDef> osSysActivityDefQueryWrapper = new QueryWrapper<OaSysActivityDef>();

        //城市code =
        if(StringUtils.isNotEmpty(activityDefSearchParam.getCityCode())) {
            osSysActivityDefQueryWrapper.eq(OaSysActivityDef.CITY, activityDefSearchParam.getCityCode());
        }

        //活动状态 =
        if(StringUtils.isNotEmpty(activityDefSearchParam.getStatus())){
            osSysActivityDefQueryWrapper.eq(OaSysActivityDef.STATUS, activityDefSearchParam.getStatus());
        }

        //活动名称 like
        if(StringUtils.isNotEmpty(activityDefSearchParam.getName())){
            osSysActivityDefQueryWrapper.like(OaSysActivityDef.NAME, activityDefSearchParam.getName());
        }

        //活动类型 =
        if(StringUtils.isNotEmpty(activityDefSearchParam.getCategory())){
            osSysActivityDefQueryWrapper.eq(OaSysActivityDef.CATEGORY, activityDefSearchParam.getCategory());
        }

        //正常记录 =0
        osSysActivityDefQueryWrapper.eq(OaSysActivityDef.DELETED, 0);

        //查询数据
        List<OaSysActivityDef> oaSysActivityDefList = oaSysActivityDefMapper.selectList(osSysActivityDefQueryWrapper);

        return this.createActivityDefSearchResult(oaSysActivityDefList);
    }

    /**
     * 创建活动定义
     * @param activityCreateParam
     */
    @Override
    @Transactional
    public void createActivityDef(ActivityCreateParam activityCreateParam) {
        //检查参数数据
        this.checkParam(activityCreateParam);

        //获取活动定义数据
        Date createDate = new Date();
        OaSysActivityDef oaSysActivityDef = this.convertActivityDef(activityCreateParam);
        //状态=00未开始
        oaSysActivityDef.setStatus("00");
        //活动编号
        oaSysActivityDef.setActivityNo("HD" +
                        DateUtil.getDateDay().replaceAll("-", "") +
                        UUID.randomUUID().toString().replace("-", "").substring(0, 2));

        Long defId = IDUtil.nextId();
        oaSysActivityDef.setId(defId);

        oaSysActivityDef.setCreateTime(createDate);
        oaSysActivityDef.setCreateUser(TokenUtil.getTokenUserId());
        oaSysActivityDef.setDeleted(0);
        oaSysActivityDef.setVersion(0L);
        oaSysActivityDef.setUpdateTime(createDate);

        oaSysActivityDefMapper.insert(oaSysActivityDef);

        //创建活动奖励方式
        iOaSysActivityRewardRuleService.createActivityRewardRule(defId, createDate, activityCreateParam.getRewardRuleList());
        //创建活动周期
        iOaSysActivityPeriodService.createActivityPeriod(createDate, oaSysActivityDef);
    }

    /**
     * 查询活动信息（根据活动定义ID）
     * @param id
     * @return
     */
    @Override
    public ActivityInfoResult queryActivityInfo(String id) {
        if(StringUtils.isEmpty(id)){
            log.error(ActivityErrorCode.paramError.getDesc());
            throw new ActivityException(ActivityErrorCode.paramError);
        }

        //查询活动定义
        QueryWrapper<OaSysActivityDef> osSysActivityDefQueryWrapper = new QueryWrapper<OaSysActivityDef>();
        osSysActivityDefQueryWrapper.eq(OaSysActivityDef.ID, id);

        OaSysActivityDef oaSysActivityDef = oaSysActivityDefMapper.selectById(id);

        if(oaSysActivityDef == null){
            log.error(ActivityErrorCode.activityDefNoneError.getDesc());
            throw new ActivityException(ActivityErrorCode.activityDefNoneError);
        }

        //获取活动奖励方式
        List<ActivityInfoRewardRuleResult> activityInfoRewardRuleResultList =
                iOaSysActivityRewardRuleService.queryActivityRewardRuleResultList(oaSysActivityDef.getId());

        if(activityInfoRewardRuleResultList == null
                ||activityInfoRewardRuleResultList.size() <= 0){
            log.error(ActivityErrorCode.paramRewardRuleError.getDesc());
            throw new ActivityException(ActivityErrorCode.paramRewardRuleError);
        }

        //获取"已结算"的活动周期
        List<ActivityInfoPeriodResult> activityInfoPeriodResultList =
                iOaSysActivityPeriodService.queryActivityPeriodResultList(oaSysActivityDef.getId());

        //创建result值
        ActivityInfoResult activityInfoResult = this.convertActivityInfoResult(oaSysActivityDef,
                activityInfoRewardRuleResultList,
                activityInfoPeriodResultList);

        //计算奖励合计
        return this.sumActivityReward(activityInfoResult);
    }

    /**
     * 活动开始
     */
    @Override
    public void beginActivity(){
        //查询活动定义
        QueryWrapper<OaSysActivityDef> osSysActivityDefQueryWrapper = new QueryWrapper<OaSysActivityDef>();

        //状态=未开始
        osSysActivityDefQueryWrapper.eq(OaSysActivityDef.STATUS, "00");
        //活动开始日期<=当前日期
        osSysActivityDefQueryWrapper.le(OaSysActivityDef.BEGIN_TIME, new Date());
        //活动有效开始时间<=当前时间
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        osSysActivityDefQueryWrapper.le(OaSysActivityDef.EFFECTIVE_TIME_START, df.format(new Date()));
        //未删除
        osSysActivityDefQueryWrapper.eq(OaSysActivityDef.DELETED, 0);

        //查询数据
        List<OaSysActivityDef> oaSysActivityDefList = oaSysActivityDefMapper.selectList(osSysActivityDefQueryWrapper);

        if(oaSysActivityDefList != null
                && oaSysActivityDefList.size() >= 0){
            for (OaSysActivityDef oaSysActivityDef : oaSysActivityDefList) {
                //设置状态=生效中
                oaSysActivityDef.setStatus("01");
                oaSysActivityDefMapper.updateById(oaSysActivityDef);
            }
        }
    }

    /**
     * 活动结束
     */
    @Override
    public void endActivity(){
        //查询活动定义
        QueryWrapper<OaSysActivityDef> osSysActivityDefQueryWrapper = new QueryWrapper<OaSysActivityDef>();

        //状态=已生效
        osSysActivityDefQueryWrapper.eq(OaSysActivityDef.STATUS, "01");
        //活动结束日期<=当前日期
        osSysActivityDefQueryWrapper.le(OaSysActivityDef.END_TIME, new Date());
        //活动有效结束时间<=当前时间
        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
        osSysActivityDefQueryWrapper.le(OaSysActivityDef.EFFECTIVE_TIME_END, df.format(new Date()));
        //未删除
        osSysActivityDefQueryWrapper.eq(OaSysActivityDef.DELETED, 0);

        //查询数据
        List<OaSysActivityDef> oaSysActivityDefList = oaSysActivityDefMapper.selectList(osSysActivityDefQueryWrapper);

        if(oaSysActivityDefList != null
                && oaSysActivityDefList.size() >= 0){
            for (OaSysActivityDef oaSysActivityDef : oaSysActivityDefList) {
                //设置状态=已结束
                oaSysActivityDef.setStatus("02");
                oaSysActivityDefMapper.updateById(oaSysActivityDef);
            }
        }
    }

    /**
     * 更新活动状态，包括活动定义和活动周期
     */
    @Override
    public void updateActivityStatus(){
        //活动开始
        this.beginActivity();
        //活动结束
        this.endActivity();
        //活动周期开始
        iOaSysActivityPeriodService.beginActivityPeriod();
        //活动周期结束
        iOaSysActivityPeriodService.endActivityPeriod();
    }

    /**
     * 根据查询的活动定义，返回活动查询结果列表
     * @param oaSysActivityDefList
     * @return
     */
    private List<ActivityDefSearchResult> createActivityDefSearchResult(List<OaSysActivityDef> oaSysActivityDefList) {
        if(oaSysActivityDefList !=null
                && oaSysActivityDefList.size() >0){
            List<ActivityDefSearchResult> activityDefSearchResultList = new ArrayList<ActivityDefSearchResult>(oaSysActivityDefList.size());
            Map<String, String> cityMap = new  HashMap<String, String>();
            for (OaSysActivityDef oaSysActivityDef : oaSysActivityDefList) {
                ActivityDefSearchResult activityDefSearchResult = new ActivityDefSearchResult();

                //ID
                activityDefSearchResult.setId(oaSysActivityDef.getId().toString());
                //活动名称
                activityDefSearchResult.setName(oaSysActivityDef.getName());
                //活动类型
                activityDefSearchResult.setCategory(oaSysActivityDef.getCategory());
                //活动城市code
                activityDefSearchResult.setCity(oaSysActivityDef.getCity());
                //活动城市name,先从map中取，没有从数据库中取(可优化统一读取放到内存中)
                String cityNameStr = cityMap.get(oaSysActivityDef.getCity());
                if(StringUtils.isEmpty(cityNameStr)) {
                    cityNameStr = this.getCityName(oaSysActivityDef.getCity());
                    cityMap.put(oaSysActivityDef.getCity(), cityNameStr);
                }
                if(StringUtils.isNoneEmpty(cityNameStr)){
                    activityDefSearchResult.setCityName(cityNameStr);
                }
                //活动状态
                activityDefSearchResult.setStatus(oaSysActivityDef.getStatus());

                //活动开始时间
                if(oaSysActivityDef.getBeginTime() != null) {
                    activityDefSearchResult.setBeginTime(DateUtil.getStringDateShort(oaSysActivityDef.getBeginTime()));
                }

                //活动结束时间
                if(oaSysActivityDef.getEndTime() != null) {
                    activityDefSearchResult.setEndTime(DateUtil.getStringDateShort(oaSysActivityDef.getEndTime()));
                }

                activityDefSearchResultList.add(activityDefSearchResult);
            }

            return activityDefSearchResultList;
        }
        else{
            return null;
        }
    }

    /**
     * 获取城市名称
     * @param cityCodeStr
     * @return
     */
    private String getCityName(String cityCodeStr) {
        if(StringUtils.isEmpty(cityCodeStr)){
            return "";
        }else {
            return oaSysActivityDefMapper.getCityNameStr(cityCodeStr);
        }
    }

    /**
     * 校验创建活动参数是否正确
     * @param activityCreateParam
     */
    private void checkParam(ActivityCreateParam activityCreateParam)
    {
        if(activityCreateParam == null)
        {
            throw new ActivityException(ActivityErrorCode.paramError);
        }
        //检查奖励方式
        if(activityCreateParam.getRewardRuleList() == null
                || activityCreateParam.getRewardRuleList().size() <= 0)
        {
            throw new ActivityException(ActivityErrorCode.paramRewardRuleError);
        }
        //检查城市
        if(activityCreateParam.getCityCodeList() == null
                || activityCreateParam.getCityCodeList().size() <= 0)
        {
            throw new ActivityException(ActivityErrorCode.paramCityError);
        }

        //检查不为空数据
        if(StringUtils.isEmpty(activityCreateParam.getName())
                || StringUtils.isEmpty(activityCreateParam.getDesc())
                || StringUtils.isEmpty(activityCreateParam.getBeginTime())
                || StringUtils.isEmpty(activityCreateParam.getEndTime())
                || StringUtils.isEmpty(activityCreateParam.getDateNumber())
                || StringUtils.isEmpty(activityCreateParam.getBalanceType())
                || StringUtils.isEmpty(activityCreateParam.getBalanceTime())){
            throw new ActivityException(ActivityErrorCode.paramEmptyError);
        }
    }

    /**
     * 根据参数创建活动定义数据
     * @param activityCreateParam
     * @return
     */
    private OaSysActivityDef convertActivityDef(ActivityCreateParam activityCreateParam){
        try {
            OaSysActivityDef oaSysActivityDef = new OaSysActivityDef();

            //名称
            oaSysActivityDef.setName(activityCreateParam.getName());
            //描述
            oaSysActivityDef.setDescription(activityCreateParam.getDesc());
            //类型
            oaSysActivityDef.setCategory(activityCreateParam.getCategory());

            List<ActivityCityCreateParam> cityCreateParamList = activityCreateParam.getCityCodeList();
            if(cityCreateParamList != null && cityCreateParamList.size() > 0)
            {
                String city = "";
                for (ActivityCityCreateParam activityCityCreateParam : cityCreateParamList)
                {
                    city = city.concat("," + activityCityCreateParam.getCityCode());
                }
                oaSysActivityDef.setCity(city.substring(1));
            }

            //司机激活几日内
            if (StringUtils.isNoneEmpty(activityCreateParam.getWithinDate())) {
                oaSysActivityDef.setWithinDate(Integer.parseInt(activityCreateParam.getWithinDate()));
            }

            //开始时间
            oaSysActivityDef.setBeginTime(DateUtil.strToDateLong(activityCreateParam.getBeginTime()));
            //结束时间
            oaSysActivityDef.setEndTime(DateUtil.strToDateLong(activityCreateParam.getEndTime()));

            //周几发放
            if (StringUtils.isNoneEmpty(activityCreateParam.getBalanceWeek())) {
                oaSysActivityDef.setBalanceWeek(Integer.parseInt(activityCreateParam.getBalanceWeek()));
            }

            //结算方式。00=次日发放；01=次周发放。
            oaSysActivityDef.setBalanceType(activityCreateParam.getBalanceType());
            //统计周期天数
            oaSysActivityDef.setDateNumber(Integer.parseInt(activityCreateParam.getDateNumber()));
            //发放时间
            oaSysActivityDef.setBalanceTime(LocalTime.parse(activityCreateParam.getBalanceTime()));

            //生效时间开始
            if(StringUtils.isNoneEmpty(activityCreateParam.getEffectiveTimeStart())) {
                oaSysActivityDef.setEffectiveTimeStart(LocalTime.parse(activityCreateParam.getEffectiveTimeStart()));
            }
            //生效时间结束
            if(StringUtils.isNoneEmpty(activityCreateParam.getEffectiveTimeEnd())) {
                oaSysActivityDef.setEffectiveTimeEnd(LocalTime.parse(activityCreateParam.getEffectiveTimeEnd()));
            }
            return oaSysActivityDef;
        }
        catch (Exception ex){
            log.error(ActivityErrorCode.paramConvertError.getDesc());
            throw new ActivityException(ActivityErrorCode.paramConvertError);
        }
    }

    /**
     * 创建活动信息返回数据
     * @param oaSysActivityDef 活动定义数据
     * @param activityInfoRewardRuleResult 活动奖励方式数据
     * @param activityInfoPeriodResult 活动周期数据
     * @return
     */
    private ActivityInfoResult convertActivityInfoResult(OaSysActivityDef oaSysActivityDef, List<ActivityInfoRewardRuleResult> activityInfoRewardRuleResult, List<ActivityInfoPeriodResult> activityInfoPeriodResult) {
        ActivityInfoResult activityInfoResult = new ActivityInfoResult();
        activityInfoResult.setActivityInfoPeriodList(activityInfoPeriodResult);
        activityInfoResult.setActivityInfoRewardRuleList(activityInfoRewardRuleResult);

        //ID
        activityInfoResult.setId(oaSysActivityDef.getId().toString());

        //活动编号
        activityInfoResult.setActivityNo(oaSysActivityDef.getActivityNo());

        OaSysUser user = oaSysUserMapper.selectById(oaSysActivityDef.getCreateUser());

        //创建人
        if(user != null) {
            activityInfoResult.setCreateUser(user.getName());
        }

        //创建时间
        activityInfoResult.setCreateTime(DateUtil.convertToStringCustom(oaSysActivityDef.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));

        //类型。00=司机记录；01=司机招募
        activityInfoResult.setCategory(oaSysActivityDef.getCategory());
        //城市code集合，用“,”进行分割。
        activityInfoResult.setCity(oaSysActivityDef.getCity());
        //城市名称集合，用“,”进行分割。
        String cityNameStr = this.getCityName(oaSysActivityDef.getCity());
        if(StringUtils.isNoneEmpty(cityNameStr)){
            activityInfoResult.setCityName(cityNameStr);
        }
        //活动状态。00=未开始；01=生效中；02=已结束
        activityInfoResult.setStatus(oaSysActivityDef.getStatus());
        //活动名称
        activityInfoResult.setName(oaSysActivityDef.getName());

        //开始时间，格式：yyyy-MM-dd
        if(oaSysActivityDef.getBeginTime() != null) {
            activityInfoResult.setBeginTime(DateUtil.getStringDateShort(oaSysActivityDef.getBeginTime()));
        }

        //结束时间，格式：yyyy-MM-dd
        if(oaSysActivityDef.getEndTime() != null){
            activityInfoResult.setEndTime(DateUtil.getStringDateShort(oaSysActivityDef.getEndTime()));
        }

        //活动描述
        activityInfoResult.setDesc(oaSysActivityDef.getDescription());

        //司机激活几日内
        if(oaSysActivityDef.getWithinDate() != null){
            activityInfoResult.setWithinDate(oaSysActivityDef.getWithinDate().toString());
        }

        //统计周期天数
        if(oaSysActivityDef.getDateNumber() != null) {
            activityInfoResult.setDateNumber(oaSysActivityDef.getDateNumber().toString());
        }

        //有效时间开始
        if(oaSysActivityDef.getEffectiveTimeStart() != null){
            activityInfoResult.setEffectiveTimeStart(oaSysActivityDef.getEffectiveTimeStart().toString());
        }

        //有效时间结束
        if(oaSysActivityDef.getEffectiveTimeEnd() != null){
            activityInfoResult.setEffectiveTimeEnd(oaSysActivityDef.getEffectiveTimeEnd().toString());
        }

        //结算方式。00=次日发放；01=次周发放。
        activityInfoResult.setBalanceType(oaSysActivityDef.getBalanceType());

        //周几发放
        if(oaSysActivityDef.getBalanceWeek() != null) {
            activityInfoResult.setBalanceWeek(oaSysActivityDef.getBalanceWeek().toString());
        }

        //发放时间
        if(oaSysActivityDef.getBalanceTime() != null){
            activityInfoResult.setBalanceTime(oaSysActivityDef.getBalanceTime().toString());
        }

        return activityInfoResult;
    }

    /**
     * 计算奖励统计数量
     * @param activityInfoResult
     * @return
     */
    private ActivityInfoResult sumActivityReward(ActivityInfoResult activityInfoResult){
        if(activityInfoResult == null){
            return  activityInfoResult;
        }

        //金额合计
        BigDecimal rewardSum = new BigDecimal(0);
        //推荐人合计
        Integer driverFromSum = 0;
        //被推荐人合计
        Integer driverToSum = 0;

        if(activityInfoResult.getActivityInfoPeriodList() != null
                && activityInfoResult.getActivityInfoPeriodList().size() > 0 ) {
            for (ActivityInfoPeriodResult activityInfoPeriodResult : activityInfoResult.getActivityInfoPeriodList()) {
                List<OaSysActivityReward> oaSysActivityRewardList =
                        iOaSysActivityRewardService.queryActivityRewardList(Long.parseLong(activityInfoPeriodResult.getId()));

                if (oaSysActivityRewardList != null
                        && oaSysActivityRewardList.size() >= 0) {
                    for (OaSysActivityReward oaSysActivityReward : oaSysActivityRewardList) {
                        rewardSum = rewardSum.add(oaSysActivityReward.getRewardAmount());

                        //推荐人计算
                        if ("00".equals(oaSysActivityReward.getDriverFrom())) {
                            driverFromSum++;
                        }

                        //被推荐人计算
                        if ("01".equals(oaSysActivityReward.getDriverFrom())) {
                            driverToSum++;
                        }
                    }
                }
            }
        }

        activityInfoResult.setTotalAmount(rewardSum.toString());
        activityInfoResult.setTotalDriverFrom(driverFromSum.toString());
        activityInfoResult.setTotalDriverTo(driverToSum.toString());

        return activityInfoResult;
    }
}
